package com.leaguefox.web.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.RunAsyncCallback;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.HasWidgets;
import com.leaguefox.web.client.common.PlayersTableCellRendererImpl;
import com.leaguefox.web.client.event.AddPlayerEvent;
import com.leaguefox.web.client.event.AddPlayerEventHandler;
import com.leaguefox.web.client.event.EditPlayerCancelledEvent;
import com.leaguefox.web.client.event.EditPlayerCancelledEventHandler;
import com.leaguefox.web.client.event.EditPlayerEvent;
import com.leaguefox.web.client.event.EditPlayerEventHandler;
import com.leaguefox.web.client.event.PlayerUpdatedEvent;
import com.leaguefox.web.client.event.PlayerUpdatedEventHandler;
import com.leaguefox.web.client.presenter.EditPlayerPresenter;
import com.leaguefox.web.client.presenter.PlayersPresenter;
import com.leaguefox.web.client.presenter.Presenter;
import com.leaguefox.web.client.view.EditPlayerView;
import com.leaguefox.web.client.view.PlayersViewImpl;
import com.leaguefox.web.shared.domain.dto.PlayerDto;

public class AppController implements Presenter, ValueChangeHandler<String> {
	private final HandlerManager eventBus;
	private final LeagueFoxServiceAsync rpcService;
	private HasWidgets container;
	private PlayersViewImpl playersView = null;
	private EditPlayerView editPlayerView;
	private PlayersPresenter playersPresenter;

	// private EditPlayerView editPlayerView = null;

	public AppController(LeagueFoxServiceAsync rpcService,
			HandlerManager eventBus) {
		this.eventBus = eventBus;
		this.rpcService = rpcService;
		bind();
	}

	private void bind() {
		History.addValueChangeHandler(this);

		eventBus.addHandler(AddPlayerEvent.TYPE, new AddPlayerEventHandler() {
			public void onAddPlayer(AddPlayerEvent event) {
				doAddNewPlayer();
			}
		});

		eventBus.addHandler(EditPlayerEvent.TYPE, new EditPlayerEventHandler() {
			public void onEditPlayer(EditPlayerEvent event) {
				doEditPlayer(event.getId());
			}
		});

		eventBus.addHandler(EditPlayerCancelledEvent.TYPE,
				new EditPlayerCancelledEventHandler() {
					public void onEditPlayerCancelled(
							EditPlayerCancelledEvent event) {
						doEditPlayerCancelled();
					}
				});

		eventBus.addHandler(PlayerUpdatedEvent.TYPE,
				new PlayerUpdatedEventHandler() {
					public void onPlayerUpdated(PlayerUpdatedEvent event) {
						doPlayerUpdated();
					}
				});
	}

	private void doAddNewPlayer() {
		History.newItem("add");
	}

	private void doEditPlayer(String id) {
		History.newItem("edit", false);
		Presenter presenter = new EditPlayerPresenter(rpcService, eventBus,
				new EditPlayerView(), id);
		presenter.go(container);
	}

	private void doEditPlayerCancelled() {
		History.newItem("list");
	}

	private void doPlayerUpdated() {
		History.newItem("list");
	}

	public void go(final HasWidgets container) {
		this.container = container;
		System.out.println("Root: " + container);
		if ("".equals(History.getToken())) {
			History.newItem("list");
		} else {
			History.fireCurrentHistoryState();
		}
	}

	public void onValueChange(ValueChangeEvent<String> event) {
		String token = event.getValue();

		if (token != null) {
			if (token.equals("list")) {

				GWT.runAsync(new RunAsyncCallback() {
					public void onFailure(Throwable caught) {
					}

					public void onSuccess() {
						// lazily initialize our views, and keep them around to
						// be reused
						//
						System.out.println("List players");
						if (playersView == null) {
							playersView = new PlayersViewImpl();
							playersView.setTableCellRenderer(new PlayersTableCellRendererImpl()); 
							System.out.println("Players view created");
						}
						playersPresenter = new PlayersPresenter(rpcService,
								eventBus, playersView);
						System.out.println("Container: " + (container != null));
						playersPresenter.go(container);
					}
				});
			} else if (token.equals("add") || token.equals("edit")) {
				GWT.runAsync(new RunAsyncCallback() {
					public void onFailure(Throwable caught) {
					}

					public void onSuccess() {
						// lazily initialize our views, and keep them around to
						// be reused
						//
						if (editPlayerView == null) {
							editPlayerView = new EditPlayerView();

						}
						new EditPlayerPresenter(rpcService, eventBus,
								editPlayerView).go(container);
					}
				});
			}
		}
	}
}
